/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pintor;

/**
 *
 * @author Jhon
 */
import java.util.ArrayList;
import processing.core.*;
import remixlab.proscene.*;

public class AlgoritmoPintor extends PApplet {

    Scene scene;
    public ArrayList<Cubos> cubitos = new ArrayList<Cubos>();
    public ArrayList<InteractiveFrame> frameA = new ArrayList<InteractiveFrame>();
    public boolean invertir = true;
    public boolean pintor = true;
    public int tamaño = 10;

    public void setup() {
        size(640, 360, P3D);
        scene = new Scene(this);
        

        hint(DISABLE_DEPTH_TEST);
        
        //hint(ENABLE_DEPTH_SORT);
    }

    public void draw() {
        background(0, 0, 0);

       /* Puntos p;
        int r,g,b,i=0;
        for(Cubos c : cubitos){

            p = new Puntos();
            p.setX((int)frameA.get(i).translation().x);
            p.setY((int)frameA.get(i).translation().y);
            p.setZ((int)frameA.get(i).translation().z);
            c.aumentar(tamaño, p);
            i++;
            
        }*/
        if(pintor){
        VisibilidadCaras();
        OrdenarCubitosPintor();}
        PintarCubos();
    }

    public void VisibilidadCaras() {
        float min = Integer.MAX_VALUE, dis;
        for(Cubos c:cubitos ){
            dis = 0;
            for (Puntos punto : c.getPuntos()) {
                dis = getDistanciaCamara(punto);
                if (dis < min) {
                    min = dis;
                    c.setPuntoMenorDistancia(punto);
                }

            }
            c.verificarPuntoenCara(c.getPuntoMenorDistancia());
            c.getPuntoMenorDistancia().setDistancia(dis);
            min = Integer.MAX_VALUE;
        }
    }

    public void PintarCubos() {
        
        float min = Integer.MAX_VALUE, dis;
        if (!cubitos.isEmpty()) {
            int i = 0;
            for (Cubos cubo : cubitos) {
                int color = 10;

                for (Superficie sup : cubo.getSuperficies()) {
                    if (invertir) {
                        if (sup.isPintar()) {
                            beginShape();
                            fill(cubo.getR() + color, cubo.getG() + color, cubo.getB() + color);
                            for (Puntos pu : sup.getPuntos()) {

                                vertex(pu.getX(), pu.getY(), pu.getZ());

                            }
                            endShape(CLOSE);
                        }
                    } else {
                        if (!sup.isPintar()) {
                            beginShape();
                            fill(cubo.getR() + color, cubo.getG() + color, cubo.getB() + color);
                            for (Puntos pu : sup.getPuntos()) {
                                vertex(pu.getX(), pu.getY(), pu.getZ());
                            }
                            endShape(CLOSE);
                        }
                    }
                    color -= 10;
                }
                i++;
            }
        }
    }

    public void keyPressed() {
        if (key == 'p') {
            Puntos p1 = new Puntos((int) scene.camera().position().x, (int) scene.camera().position().y, (int) scene.camera().position().z);
            Puntos p2 = new Puntos(p1.getX(), p1.getY() + 10, p1.getZ());
            Puntos p3 = new Puntos(p2.getX() + 10, p2.getY(), p2.getZ());
            Puntos p4 = new Puntos(p1.getX() + 10, p1.getY(), p1.getZ());
            Puntos p5 = new Puntos(p4.getX(), p4.getY(), p4.getZ() + 10);
            Puntos p6 = new Puntos(p5.getX() - 10, p5.getY(), p5.getZ());
            Puntos p7 = new Puntos(p6.getX(), p6.getY() + 10, p6.getZ());
            Puntos p8 = new Puntos(p5.getX(), p5.getY() + 10, p5.getZ());
            Cubos aux = new Cubos(p1, p2, p3, p4, p5, p6, p7, p8);
            aux.setR((int) (Math.random() * 255));
            aux.setG((int) (Math.random() * 255));
            aux.setB((int) (Math.random() * 255));
            cubitos.add(aux);
            InteractiveFrame f = new InteractiveFrame(scene);
             //aca es donde agrega los interactive frame.. rebreve simplemente le digo cual es la traslacion y sale q es la misma posicion del punto de control...
             f.setTranslation((int)scene.camera().position().x,(int)scene.camera().position().y,(int)scene.camera().position().z);
             frameA.add(f);

        } else if (key == 'i') {
            invertir = !invertir;
        } else if (key == '+') {
            if (tamaño < 30) {
                tamaño++;
            }
            for (Cubos c : cubitos) {
                c.aumentar(tamaño);
            }

        } else if (key == '-') {
            if (tamaño > 5) {
                tamaño--;
            }
            for (Cubos c : cubitos) {
                c.aumentar(tamaño);
            }
        } else if (key == 'o') {
            pintor = !pintor;
            if (pintor) {
                System.out.println("PINTOR ON");
            } else {
                System.out.println("PINTOR OFF");
            }
        }
    }

    public float getDistanciaCamara(Puntos p) {
        PVector pV = scene.camera().frame().coordinatesOf(new PVector(p.getX(), p.getY(), p.getZ()));
        return (float) Math.sqrt((pV.x) * (pV.x) + (pV.y) * (pV.y) + (pV.z) * (pV.z));
    }

    public void OrdenarCubitosPintor() {
        Cubos aux;
        for (int i = 0; i < cubitos.size(); i++) {
            for (int j = i; j < cubitos.size(); j++) {
                if (cubitos.get(i).getPuntoMenorDistancia().getDistancia() < cubitos.get(j).getPuntoMenorDistancia().getDistancia()) {
                    aux = cubitos.get(i);
                    cubitos.set(i, cubitos.get(j));
                    cubitos.set(j, aux);
                }

            }

        }
    }

    public static void main(String args[]) {
        PApplet.main(new String[]{"pintor.AlgoritmoPintor"});
    }
}
